package org.tp.edifact.config;

import static org.junit.Assert.*;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.BeforeClass;
import org.junit.Test;

public class TestEdifactConfigurator {

   private static final Logger log_ = LogManager.getLogger(TestEdifactConfigurator.class.getName());
   private static Integer hashCode_ = null;

   @BeforeClass
   public static void setUpBeforeClass() throws Exception {
      log_.debug("Instantiating the class for the first time ...");
      EdifactConfigurator ec = EdifactConfigurator.getInstance();
      hashCode_ = new Integer(ec.hashCode());
      log_.debug("Instance hash code: " + hashCode_);
   }

   @Test
   public void testGetInstance() {
      log_.debug("testGetInstance()");
      log_.debug("Obtaining a class instance ...");
      EdifactConfigurator ec = EdifactConfigurator.getInstance();
      int hc = ec.hashCode();
      log_.debug("Obtained an instance of: \"" + ec.getClass().getName() + "\". Hash code: " + hc);
      assertEquals("Hash code must be the same.", hashCode_.intValue(), hc);
      
      log_.debug("Getting a second instance ...");
      EdifactConfigurator ec2 = EdifactConfigurator.getInstance();
      hc = ec2.hashCode();      
      log_.debug("Obtained an instance of: \"" + ec2.getClass().getName() + "\". Hash code: " + hc);
      assertEquals("Hash code must be the same.", hashCode_.intValue(), hc);

      log_.debug("Instances must be the same.");
      assertEquals("Must be the same object.", ec, ec2);
      log_.debug("Instances are the same.");
   }

   @Test
   public void testGetEncodingsMap() {
      log_.debug("testGetEncodingsMap()");
      log_.debug("Obtaining a class instance ...");
      EdifactConfigurator ec = EdifactConfigurator.getInstance();
      int hc = ec.hashCode();
      log_.debug("Obtained an instance of: \"" + ec.getClass().getName() + "\". Hash code: " + hc);
      assertEquals("Hash code must be the same.", hashCode_.intValue(), hc);

      log_.debug("Getting encodings ...");
      
      Map<String, String> encodings = ec.getEncodingsMap();
      
      log_.debug("Number of encodings: " + encodings.size());
      
      Set<String> keys = encodings.keySet();
      Iterator<String> it = keys.iterator();
      
      while (it.hasNext()) {
         String k = it.next();
         String c = encodings.get(k);
         
         log_.debug("Encoding key       : \"" + k + "\"");
         log_.debug("Encoding class     : \"" + c + "\"");
      }      
   }

   @Test
   public void testGetEventDrivenDecodersMap() {
      log_.debug("testGetEventDrivenDecodersMap()");
      log_.debug("Obtaining a class instance ...");
      EdifactConfigurator ec = EdifactConfigurator.getInstance();
      int hc = ec.hashCode();
      log_.debug("Obtained an instance of: \"" + ec.getClass().getName() + "\". Hash code: " + hc);
      assertEquals("Hash code must be the same.", hashCode_.intValue(), hc);

      log_.debug("Getting event driven decoders map ...");
      
      Map<String, String> eddm = ec.getEventDrivenDecodersMap();
      
      log_.debug("Number of decoders: " + eddm.size());
      
      Set<String> keys = eddm.keySet();
      Iterator<String> it = keys.iterator();
      
      while (it.hasNext()) {
         String k = it.next();
         String c = eddm.get(k);
         
         log_.debug("Decoder key       : \"" + k + "\"");
         log_.debug("Decoder class     : \"" + c + "\"");
      }      
   }

   @Test
   public void testGetDefaultEventDrivenDecoderName() {
      log_.debug("testGetDefaultEventDrivenDecoderName()");
      log_.debug("Obtaining a class instance ...");
      EdifactConfigurator ec = EdifactConfigurator.getInstance();
      int hc = ec.hashCode();
      log_.debug("Obtained an instance of: \"" + ec.getClass().getName() + "\". Hash code: " + hc);
      assertEquals("Hash code must be the same.", hashCode_.intValue(), hc);

      log_.debug("Getting default event driven decoder ...");
      String dd = ec.getDefaultEventDrivenDecoderName();      
      log_.debug("Default event driven decoder name : " + dd);
      
      Map<String, String> eddm = ec.getEventDrivenDecodersMap();      
      assertTrue("Key must have a value.", eddm.containsKey(dd));
      log_.debug("Default event driven decoder class: " + eddm.get(dd));      
   }

   @Test
   public void testGetSequentialDecodersMap() {
      log_.debug("testGetSequentialDecodersMap()");
      log_.debug("Obtaining a class instance ...");
      EdifactConfigurator ec = EdifactConfigurator.getInstance();
      int hc = ec.hashCode();
      log_.debug("Obtained an instance of: \"" + ec.getClass().getName() + "\". Hash code: " + hc);
      assertEquals("Hash code must be the same.", hashCode_.intValue(), hc);

      log_.debug("Getting sequential decoders map ...");
      
      Map<String, String> sdm = ec.getSequentialDecodersMap();
      
      log_.debug("Number of decoders: " + sdm.size());
      
      Set<String> keys = sdm.keySet();
      Iterator<String> it = keys.iterator();
      
      while (it.hasNext()) {
         String k = it.next();
         String c = sdm.get(k);
         
         log_.debug("Decoder key       : \"" + k + "\"");
         log_.debug("Decoder class     : \"" + c + "\"");
      }      
   }

   @Test
   public void testGetDefaultSequentialDecoderName() {
      log_.debug("testGetDefaultSequentialDecoderName()");
      log_.debug("Obtaining a class instance ...");
      EdifactConfigurator ec = EdifactConfigurator.getInstance();
      int hc = ec.hashCode();
      log_.debug("Obtained an instance of: \"" + ec.getClass().getName() + "\". Hash code: " + hc);
      assertEquals("Hash code must be the same.", hashCode_.intValue(), hc);

      log_.debug("Getting default sequential decoder ...");
      String dd = ec.getDefaultSequentialDecoderName();      
      log_.debug("Default sequential decoder name : " + dd);
      
      Map<String, String> eddm = ec.getSequentialDecodersMap();      
      assertTrue("Key must have a value.", eddm.containsKey(dd));
      log_.debug("Default sequential decoder class: " + eddm.get(dd));      
   }

}
